#include "Dx11Renderer.h"

namespace NBGUI
{
	void Dx11Renderer::InitDx11(unsigned int width,
		unsigned int height,
		unsigned int freshRate,//hard code 60
		HWND window,
		bool fullscreen)
	{
		screenWidth = width;
		screenHeight = height;

		DXGI_SWAP_CHAIN_DESC sd =
		{
			{ width, height, { 60, 1 }, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED, DXGI_MODE_SCALING_UNSPECIFIED },
			{ 1, 0 },
			DXGI_USAGE_RENDER_TARGET_OUTPUT,
			1,
			window,
			!fullscreen,
			DXGI_SWAP_EFFECT_DISCARD,
			0
		};

		D3D_FEATURE_LEVEL featurelevels[] = 
		{
			D3D_FEATURE_LEVEL_11_0,
			D3D_FEATURE_LEVEL_10_1,
			D3D_FEATURE_LEVEL_10_0,
		};

		D3D_FEATURE_LEVEL featurelevelpicked ;

		unsigned int createdeviceflags = 0;
#ifdef _DEBUG
		createdeviceflags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

		HV(D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createdeviceflags, featurelevels, sizeof(featurelevels)/sizeof(D3D_FEATURE_LEVEL), D3D11_SDK_VERSION,
			&sd, &m_swapChain, &m_device, &featurelevelpicked, &m_context));
		

		ID3D11Texture2D *backbuffer;
		HV(m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void **)&backbuffer));
		HV(m_device->CreateRenderTargetView(backbuffer, NULL, &m_rtview));
		HV(backbuffer->Release());

		D3D11_TEXTURE2D_DESC desc =
		{
			width, height,
			1, 1,
			DXGI_FORMAT_D32_FLOAT,
			{ 1, 0 },
			D3D11_USAGE_DEFAULT,
			D3D11_BIND_DEPTH_STENCIL,
			0, 0
		};
		ID3D11Texture2D *tex = NULL;
		HV(m_device->CreateTexture2D(&desc, NULL, &tex));

		//////////////////////////////////////////////////////////////////////////
		// Initialize the description of the stencil state.
		D3D11_DEPTH_STENCIL_DESC depthStencilDesc;
		ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc));

		// Set up the description of the stencil state.
		depthStencilDesc.DepthEnable = false;
		depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
		depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS;

		depthStencilDesc.StencilEnable = true;
		depthStencilDesc.StencilReadMask = 0xFF;
		depthStencilDesc.StencilWriteMask = 0xFF;

		// Stencil operations if pixel is front-facing.
		depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
		depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
		depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
		depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;

		// Stencil operations if pixel is back-facing.
		depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
		depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;
		depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
		depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
		ID3D11DepthStencilState* depthStencilState;
		HV(m_device->CreateDepthStencilState(&depthStencilDesc, &depthStencilState));
		// Set the depth stencil state.
		m_context->OMSetDepthStencilState(depthStencilState, 1);
		HV(depthStencilState->Release());
		D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc;
		// Initialize the depth stencil view.
		ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc));

		// Set up the depth stencil view description.
		depthStencilViewDesc.Format = desc.Format;
		depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
		depthStencilViewDesc.Texture2D.MipSlice = 0;


		HV(m_device->CreateDepthStencilView(tex, &depthStencilViewDesc, &m_dsview));
		HV(tex->Release());




		m_context->OMSetRenderTargets(1, &m_rtview, m_dsview);

		D3D11_RASTERIZER_DESC rasterizerstate = { D3D11_FILL_SOLID, D3D11_CULL_BACK, true, 0, 0, 0, true, false, false, false };
		HV(m_device->CreateRasterizerState(&rasterizerstate, &m_rs));
		m_context->RSSetState(m_rs); 

		D3D11_VIEWPORT viewport = {0, 0, static_cast<FLOAT>(width), static_cast<FLOAT>(height), 0, 1};
		m_context->RSSetViewports(1, &viewport);

		//////////////////////////////////////////////////////////////////////////
		D3D11_BLEND_DESC blendStateDescription; 
		ZeroMemory(&blendStateDescription,sizeof(D3D11_BLEND_DESC));
		blendStateDescription.RenderTarget[0].BlendEnable = TRUE;
		blendStateDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
		blendStateDescription.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
		blendStateDescription.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
		blendStateDescription.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
		blendStateDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
		blendStateDescription.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
		blendStateDescription.RenderTarget[0].RenderTargetWriteMask = 0x0f;


		ID3D11BlendState* blendstate;
		float blendFactor[] = {0,0, 0, 0};

		HRESULT r = m_device->CreateBlendState(&blendStateDescription,&blendstate);
		m_context->OMSetBlendState(blendstate,blendFactor,0xffffffff);

		blendstate->Release();
		//////////////////////////////////////////////////////////////////////////

		


		// Setup the projection matrix.
		float fieldOfView = (float)D3DX_PI / 4.0f; // 45 degree
		float screenAspect = (float)width / (float)height;

		// Create the projection matrix for 3D rendering.
		D3DXMatrixPerspectiveFovLH(&m_projectionMatrix, fieldOfView, screenAspect, 0.1f, 1000.0f);

		// Initialize the world matrix to the identity matrix.
		D3DXMatrixIdentity(&m_worldMatrix);

		// Create an orthographic projection matrix for 2D rendering.
		D3DXMatrixOrthoLH(&m_orthoMatrix, (float)width, (float)height, 0.1f, 1000.0f);


		m_effectVec.push_back( setupShaders(L"testLayout.fx") );

		m_lastShaderIdx = m_effectVec.size() - 1;
	}


	void Dx11Renderer::InitDx11(unsigned int width,
		unsigned int height,
		unsigned int freshRate,//hard code 60
		HWND window,
		bool fullscreen,
		ID3D11Device* device,
		ID3D11DeviceContext* context)
	{
		m_device = device;
		m_context = context;
		m_hWnd = window;

		screenWidth = width;
		screenHeight = height;

		D3D11_DEPTH_STENCIL_DESC depthStencilDesc;
		ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc));

		// Set up the description of the stencil state.
		depthStencilDesc.DepthEnable = false;
		depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
		depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS;

		depthStencilDesc.StencilEnable = true;
		depthStencilDesc.StencilReadMask = 0xFF;
		depthStencilDesc.StencilWriteMask = 0xFF;

		// Stencil operations if pixel is front-facing.
		depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
		depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
		depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
		depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;

		// Stencil operations if pixel is back-facing.
		depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
		depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;
		depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
		depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
		
		HV(m_device->CreateDepthStencilState(&depthStencilDesc, &depthStencilState));
		// Set the depth stencil state.
		m_context->OMSetDepthStencilState(depthStencilState, 1);
		
 

		//////////////////////////////////////////////////////////////////////////
		D3D11_BLEND_DESC blendStateDescription; 
		ZeroMemory(&blendStateDescription,sizeof(D3D11_BLEND_DESC));
		blendStateDescription.RenderTarget[0].BlendEnable = TRUE;
		blendStateDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
		blendStateDescription.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
		blendStateDescription.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
		blendStateDescription.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
		blendStateDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
		blendStateDescription.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
		blendStateDescription.RenderTarget[0].RenderTargetWriteMask = 0x0f;


		ID3D11BlendState* blendstate;
		float blendFactor[] = {0,0, 0, 0};

		HRESULT r = m_device->CreateBlendState(&blendStateDescription,&blendstate);
		m_context->OMSetBlendState(blendstate,blendFactor,0xffffffff);

		blendstate->Release();
		//////////////////////////////////////////////////////////////////////////




		// Setup the projection matrix.
		float fieldOfView = (float)D3DX_PI / 4.0f; // 45 degree
		float screenAspect = (float)width / (float)height;

		// Create the projection matrix for 3D rendering.
		D3DXMatrixPerspectiveFovLH(&m_projectionMatrix, fieldOfView, screenAspect, 0.1f, 1000.0f);

		// Initialize the world matrix to the identity matrix.
		D3DXMatrixIdentity(&m_worldMatrix);

		// Create an orthographic projection matrix for 2D rendering.
		D3DXMatrixOrthoLH(&m_orthoMatrix, (float)width, (float)height, 0.1f, 35000.0f);


		m_effectVec.push_back( setupShaders(L"testLayout.fx") );

		m_lastShaderIdx = m_effectVec.size() - 1;
	}

	Dx11Renderer::Dx11Renderer( HWND hWnd, unsigned int width, unsigned int height):m_hWnd(hWnd),m_lastShaderIdx(-1)
	{
		InitDx11(width,height,60,hWnd,false);

		InitTexture();//load default one
		
		
	}

	Dx11Renderer::Dx11Renderer(HWND hWnd, ID3D11Device* device,ID3D11DeviceContext* context, unsigned int width, unsigned int height )
	{
		InitDx11(width,height,60,hWnd,false,device,context);

		InitTexture();//load default one
	}

	Dx11Renderer::~Dx11Renderer()
	{
// 		m_device->Release();
// 		m_context->Release();
// 		m_swapChain->Release();
// 		m_rtview->Release();
// 		m_dsview->Release();
// 		m_rs->Release();


		

		for (size_t i = 0; i< m_inputLayoutVec.size();++i)
		{
			m_inputLayoutVec[i]->Release();
		}
		m_inputLayoutVec.clear();

		for (size_t i = 0; i< m_effectVec.size();++i)
		{
			m_effectVec[i]->Release();
		}
		m_effectVec.clear();

		for (size_t i = 0; i< texList.size();++i)
		{
			static_cast<ID3D11ShaderResourceView*>(texList[i]->pTex)->Release();
			delete texList[i];
		}
		texList.clear();
		
		for (size_t i = 0; i< m_vboVec.size();++i)
		{
			m_vboVec[i]->Release();
		}
		m_vboVec.clear();

		for (size_t i = 0; i< m_iboVec.size();++i)
		{
			m_iboVec[i]->Release();
		}
		m_iboVec.clear();

		HV(depthStencilState->Release());
	}

	int Dx11Renderer::runMainLoop()
	{
		//calculateCenter(m_hWnd);
		MSG msg;
		while (true)
		{
			if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
			{
				if (msg.message == WM_QUIT)
				{
					break;
				}
				TranslateMessage(&msg);
				DispatchMessage(&msg);	
			}else
			{
				update();
			}
		}
		return (int)msg.wParam;
	}

	void Dx11Renderer::update()
	{
		//don't call cuz user has new update
		float color[4] = {0.5f,0.6f,0.7f,1.0f}; 
		m_context->ClearRenderTargetView(m_rtview, color );
		m_context->ClearDepthStencilView(m_dsview,D3D11_CLEAR_DEPTH,1,0);
		//updateFrame
		m_swapChain->Present(1,0);
	}

	ID3DX11Effect* Dx11Renderer::setupShaders(LPCTSTR fxName)
	{
		ID3D10Blob *fxblob = NULL, *errblob = NULL;
		if(FAILED(D3DX11CompileFromFile(fxName, NULL, NULL, "", "fx_5_0", 
			D3D10_SHADER_ENABLE_STRICTNESS, 0, NULL, &fxblob, &errblob, NULL))) 
		{
			char* erstr = (char*)errblob->GetBufferPointer();
			errblob->Release();
		}
		ID3DX11Effect* effect;
		HV(D3DX11CreateEffectFromMemory(fxblob->GetBufferPointer(), fxblob->GetBufferSize(), 0, m_device, &effect));
		fxblob->Release();

		return effect;

	}

	void Dx11Renderer::swapBuffer(bool sync)
	{
		m_swapChain->Present(sync,0);
	}

	void Dx11Renderer::drawIndexed( unsigned int startIdx, unsigned int len, int vboId, int iboId)
	{
		static unsigned int stride = sizeof(Vertex); 
		static unsigned int offset = 0;
		
		m_context->IASetVertexBuffers(0,1, &m_vboVec[vboId],&stride,&offset);
		m_context->IASetInputLayout(m_inputLayoutVec[vboId]);	
		m_context->IASetIndexBuffer(m_iboVec[iboId], DXGI_FORMAT_R32_UINT, 0);

		_applyLastShaderResource();

		m_context->IASetPrimitiveTopology( D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
		m_context->DrawIndexed(len,startIdx,0);
	}

	void Dx11Renderer::beforeFrame()
	{
		//static float color[4] = {0.5f,0.6f,0.7f,1.0f}; 
		//m_context->ClearRenderTargetView(m_rtview, color );
		//m_context->ClearDepthStencilView(m_dsview,D3D11_CLEAR_DEPTH,1,0);
 
		buildCamMatrix();

		HV(m_effectVec[m_lastShaderIdx]->GetVariableByName("modelMat")->AsMatrix()->SetMatrix(m_worldMatrix));
		HV(m_effectVec[m_lastShaderIdx]->GetVariableByName("viewMat")->AsMatrix()->SetMatrix(m_viewMatrix));
		HV(m_effectVec[m_lastShaderIdx]->GetVariableByName("projMat")->AsMatrix()->SetMatrix(m_orthoMatrix));
		D3DXMATRIX temp = m_worldMatrix * m_viewMatrix * m_orthoMatrix;
	}

	void Dx11Renderer::_applyLastShaderResource()
	{
		assert(m_lastShaderIdx >= 0);
		HV(m_effectVec[m_lastShaderIdx]->GetTechniqueByIndex(0)->GetPassByIndex(0)->Apply(0,m_context));
		//dx only apply all draw calls after you apply the shader
	}

	void Dx11Renderer::applyTexture(unsigned int idx)
	{
		m_effectVec[m_lastShaderIdx]->GetVariableByName("diftex")->AsShaderResource()->SetResource(static_cast<ID3D11ShaderResourceView *>(texList[idx]->pTex));
	}

	void Dx11Renderer::applyShader(unsigned int idx = 0)
	{
		//m_lastShaderIdx = idx;
	}

	void Dx11Renderer::loadTex( Texture* tex )
	{
		ID3D11Texture2D* pTexture2D ;  
		ID3D11ShaderResourceView* srv;
		D3D11_SHADER_RESOURCE_VIEW_DESC rvDesc;
		ZeroMemory(&rvDesc,sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC));
		D3D11_TEXTURE2D_DESC tDesc;
		ZeroMemory(&tDesc,sizeof(D3D11_TEXTURE2D_DESC));
		tDesc.Height = tex->height;
		tDesc.Width = tex->width;
		tDesc.Usage = D3D11_USAGE_DEFAULT;
		tDesc.CPUAccessFlags = 0;
		tDesc.MipLevels = 1;
		tDesc.ArraySize = 1;
		tDesc.SampleDesc.Count = 1; 
		tDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE| D3D11_BIND_RENDER_TARGET;;
		tDesc.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS;

		D3DX11CreateTextureFromFile( m_device, tex->path.c_str(), NULL, NULL, (ID3D11Resource**)(&pTexture2D), NULL );

		rvDesc.Format = tDesc.Format;

		rvDesc.Texture2D.MipLevels = -1;
		rvDesc.Texture2D.MostDetailedMip = 0;
		rvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;

		m_device->CreateShaderResourceView( pTexture2D, &rvDesc, &srv );

		tex->pTex = srv;

		pTexture2D->Release();
	}


	int Dx11Renderer::createTexture(const wchar_t* name, void* data, unsigned int width, unsigned int height, 
		unsigned int format, unsigned int type, int colorLen = 4)
	{
		ID3D11Texture2D * pTexture = _createDX11Tex2D(data,width,height,format,type, colorLen);
		ID3D11ShaderResourceView* srv = _createShaderResourceView(pTexture);

		pTexture->Release();
		Texture* newTex = new Texture(width,height);
		newTex->pTex = srv;
		texList.push_back(newTex);
		return (int)texList.size()-1;
	}

	ID3D11Texture2D* Dx11Renderer::_createDX11Tex2D(void* data, uint width, uint height, uint format, uint type, int colorLen)
	{
		D3D11_TEXTURE2D_DESC tDesc;
		ZeroMemory(&tDesc,sizeof(D3D11_TEXTURE2D_DESC));
		tDesc.Height = height;
		tDesc.Width = width;
		tDesc.Usage = D3D11_USAGE_DEFAULT;
		tDesc.CPUAccessFlags = 0;
		tDesc.MipLevels = 0;
		tDesc.ArraySize = 1;
		tDesc.SampleDesc.Count = 1;
		tDesc.Format = (DXGI_FORMAT)format;
		tDesc.BindFlags =  D3D11_BIND_SHADER_RESOURCE| D3D11_BIND_RENDER_TARGET;
		tDesc.MiscFlags =  D3D11_RESOURCE_MISC_GENERATE_MIPS;
		


		ID3D11Texture2D * pTexture;
		HV(  m_device->CreateTexture2D( &tDesc, NULL, &pTexture ));
		//////////////////////////////////////////////////////////////////////////
		tDesc.Usage = D3D11_USAGE_STAGING;
		tDesc.MipLevels = 1;//only 1 level 
		tDesc.CPUAccessFlags =/* D3D11_CPU_ACCESS_WRITE|*/D3D11_CPU_ACCESS_READ;
		tDesc.BindFlags =  0;
		tDesc.MiscFlags =  0;

		D3D11_SUBRESOURCE_DATA subRd;
		ZeroMemory(&subRd, sizeof(D3D11_SUBRESOURCE_DATA));
		subRd.pSysMem = data;
		subRd.SysMemPitch =  colorLen * width;//hack 

		ID3D11Texture2D * pTexture_src;
		HV(  m_device->CreateTexture2D( &tDesc, &subRd, &pTexture_src ));
		//////////////////////////////////////////////////////////////////////////
		//copy data
		D3D11_BOX sourceRegion;
		sourceRegion.left = 0;
		sourceRegion.right = width;
		sourceRegion.top = 0;
		sourceRegion.bottom = height;
		sourceRegion.front = 0;
		sourceRegion.back = 1;

		m_context->CopySubresourceRegion( pTexture, 0, 0, 0, 0, pTexture_src, 0, &sourceRegion );
		pTexture_src->Release();
		return pTexture;
	}


	ID3D11ShaderResourceView* Dx11Renderer::_createShaderResourceView(ID3D11Texture2D* tex)
	{
		ID3D11ShaderResourceView* srv;
		D3D11_SHADER_RESOURCE_VIEW_DESC rvDesc;
		ZeroMemory(&rvDesc,sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC));
		D3D11_TEXTURE2D_DESC des;
		tex->GetDesc(&des);
		rvDesc.Format = des.Format;
		rvDesc.Texture2D.MipLevels = -1;
		rvDesc.Texture2D.MostDetailedMip = 0;

		rvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;

		HV(m_device->CreateShaderResourceView(tex, &rvDesc, &srv));
		m_context->GenerateMips(srv);
		return srv;
	}

	void Dx11Renderer::InitTexture()
	{
		//init default png
		texList.push_back(new Texture(L"default.png"));
		loadTex(texList[0]);
	}


	int Dx11Renderer::createTexture(const char* path)
	{
		texList.push_back(new Texture(path));
		loadTex(texList.back());
		return (int)texList.size() - 1;
	}



	int Dx11Renderer::createVBO( void* buff, unsigned int length, unsigned int verSize ,unsigned int shIdx, char* fmt)
	{
		D3D11_SUBRESOURCE_DATA srd = { buff, 0, 0 };
		ID3D11Buffer* newVBO;
		HV(m_device->CreateBuffer(&CD3D11_BUFFER_DESC(length * verSize, D3D11_BIND_VERTEX_BUFFER, D3D11_USAGE_DYNAMIC,D3D11_CPU_ACCESS_WRITE), &srd, &newVBO));

		int len = strlen(fmt);
		D3D11_INPUT_ELEMENT_DESC *decl = new D3D11_INPUT_ELEMENT_DESC[len];
		memset(decl, 0, sizeof(D3D11_INPUT_ELEMENT_DESC)*len);
		int offset = 0, semidx = 0;

		for(int i = 0; i<len; i++)
		{
			D3D11_INPUT_ELEMENT_DESC &d = decl[i];


			switch(fmt[i])
			{
			case 'P': d.SemanticName = "POSITION"; d.Format = DXGI_FORMAT_R32G32B32_FLOAT; offset = 0 ; break;
			case 'T': d.SemanticName = "TEXCOORD"; d.Format = DXGI_FORMAT_R32G32_FLOAT;    offset = 12;d.SemanticIndex = semidx++; break;
			case 'C': d.SemanticName = "COLOR";    d.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;  offset = 20; break;
			default: assert(0);
			}

			d.AlignedByteOffset = offset;
		}

 

		ID3DX11Effect* effect = m_effectVec[shIdx];
		D3DX11_PASS_DESC passDesc;
		ID3DX11EffectTechnique* pRenderTechnique = effect->GetTechniqueByIndex(0);//default technique  

		ID3D11InputLayout* inputLayout;
		HV(pRenderTechnique->GetPassByIndex(0)->GetDesc(&passDesc));
		HV(m_device->CreateInputLayout(decl,len,passDesc.pIAInputSignature,passDesc.IAInputSignatureSize,&inputLayout));
		 
		m_inputLayoutVec.push_back(inputLayout);

		delete[] decl; 
		m_vboVec.push_back(newVBO);
		return m_vboVec.size()-1;
	}

	int Dx11Renderer::createIBO( void* pIBO, unsigned int length)
	{
		D3D11_SUBRESOURCE_DATA srd = {pIBO, 0, 0 };
		ID3D11Buffer* newIBO;
		HV(m_device->CreateBuffer(&CD3D11_BUFFER_DESC( length*sizeof(unsigned int), D3D11_BIND_INDEX_BUFFER, D3D11_USAGE_IMMUTABLE), &srd, &newIBO));
		m_iboVec.push_back(newIBO);
		return m_iboVec.size() - 1;
	}

	bool Dx11Renderer::updateVBO( void* newBuff, unsigned int start,unsigned int length,unsigned int verSize, int vboId)//verSize = sizeof(Vertex)
	{
		D3D11_MAPPED_SUBRESOURCE resource;
		HRESULT hResult = m_context->Map(m_vboVec[vboId], 0,
			D3D11_MAP_WRITE_DISCARD, 0, &resource);

		if(hResult != S_OK)
			return false;

 
		memcpy_s((byte*)resource.pData + start,length * verSize,newBuff,length * verSize) ;
	 
		m_context->Unmap(m_vboVec[vboId], 0);
		
		return true;

	}

	void Dx11Renderer::deleteVBO(int vboId)
	{
		m_vboVec[vboId]->Release();
	}

	void Dx11Renderer::deleteIBO(int iboId)
	{
		m_iboVec[iboId]->Release();
	}

	void Dx11Renderer::initDrawing( void* vbuff, unsigned int vLength, void* ibuff, unsigned int iLength )
	{
		createVBO(vbuff,vLength,sizeof(Vertex),0,"PTC");
		createIBO(ibuff,iLength);
	}

	void Dx11Renderer::buildCamMatrix()
	{
		D3DXVECTOR3 up(0,1,0), position(0,0,-1), lookAt(0,0,1);
		
		D3DXMatrixLookAtLH(&m_viewMatrix, &position, &lookAt, &up);
		return;
	}

	void Dx11Renderer::turnOffDepth()
	{
		m_context->OMSetDepthStencilState(depthStencilState, 1);
	}






}